home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / CD-ROM Tools / SkandalfoCDP12 / source / scdp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-27  |  99.1 KB  |  1,784 lines

  1. #include "SCDP.h"
  2. #include "scdplogo.h"
  3.  
  4. enum ReturnIDs
  5. {
  6.     ID_Play=1, ID_Pause, ID_Stop, ID_Previous, ID_Next, ID_Rewind, ID_FastForward, ID_Eject,
  7.     ID_Volume,ID_ProgramL,ID_Shuffle,ID_Repeat,
  8.     ID_TrackSelect,ID_List,ID_ProgramR,
  9.     ID_Use,ID_Save,ID_Confirm,ID_ChangeActive,ID_PUse,ID_PSave,ID_PInsert,
  10.     /* For menus */
  11.     MEN_PROJECT,MEN_ABOUT,MEN_ABOUTMUI,MEN_QUIT,MEN_SETTINGS,MEN_MUI
  12.  
  13. };
  14.  
  15. #define min(a,b) (((a)<(b))?(a):(b))
  16.  
  17. #define MyImageButton(image,key,help) ImageObject,MUIA_Background,MUII_ButtonBack, ButtonFrame, MUIA_Weight, 0, MUIA_Image_Spec,"4:PROGDIR:images/" image,MUIA_ControlChar, key, MUIA_InputMode,MUIV_InputMode_RelVerify,MUIA_ShortHelp,glstr(help), End
  18. #define MyImage(image) ImageObject, MUIA_Weight, 0, MUIA_Image_Spec,"4:PROGDIR:images/" image, End
  19. #define MyImageButton2(image,key,help) ImageObject, MUIA_Background,MUII_ButtonBack, ButtonFrame, MUIA_Weight, 0, MUIA_Image_Spec,"4:PROGDIR:images/" image,MUIA_ControlChar, key, MUIA_InputMode,MUIV_InputMode_Toggle,MUIA_ShortHelp,glstr(help), End
  20.  
  21. #define max(a,b) ((a)>(b))?(a):(b)
  22. #define min(a,b) ((a)<(b))?(a):(b)
  23.  
  24. /* Function prototypes */
  25. int DoScsiCmd(UBYTE *data, int datasize, UBYTE *cmd, int cmdsize, UBYTE flags);
  26. void CDEject(void);
  27. void CDLoad(void);
  28. void CDStop(void);
  29. void CDGetPos(BOOL settimer);
  30. void CDSetVolume(int volume);
  31. void CDResume(void);
  32. void CDPause(void);
  33. void CDPlay(int start, int length);
  34. void CDReadContents(void);
  35. void DoShuffle(void);
  36. void DoProgram(void);
  37. void FillList(void);
  38.  
  39. /* Some global vars */
  40. enum status_enum {NODISK,STOPPED,PAUSED,PLAYING} status=NODISK;     /* CD status*/
  41. enum pstatus_enum {NORMAL,PROGRAM,SHUFFLE} pstatus=NORMAL;          /* Program status */
  42. UBYTE track=0;                                                      /* Track being played */
  43. ULONG actualindex=0;/* address in actualtrack */
  44. ULONG totalindex=0; /* address in CD */
  45. UBYTE validTOC=0;   /* 1=We have read a valid TOC, 0=No */
  46. UBYTE *TOCbuf;      /* Buffer for Table Of Contents */
  47. UBYTE TOClength;    /* Number of tracks */
  48. UBYTE TOCflags[100];/* 0=CDDA, 1=Data */
  49. ULONG TOCaddr[100]; /* Track starts */
  50. char TOCCDID[20];           /* Id string of CD */
  51. char TOCCDtitle[128];       /* Title of actual CD */
  52. char TOCCDartist[128];      /* Artist */
  53.  
  54. UBYTE programmed[101];  /* List of programmed/shuffled tracks */
  55. UBYTE pprog[101];      /* Definitely programmed tracks */
  56. UBYTE pactual;
  57.  
  58. BOOL refresh=FALSE;
  59. BOOL trayout=FALSE;     /* For Eject/Load */
  60. BOOL onevalid=FALSE;     /* Is there at least one CDDA track? */
  61.  
  62. BOOL userstop=TRUE; /* We want CDROM stopped */
  63. UBYTE actuate=0;
  64. UBYTE skip=3;       /* Kludge for waiting for a track's begin */
  65.  
  66. /* Global vars for timing */
  67. struct timerequest *tioreq;
  68. MSGPORT *tmsgport;
  69.  
  70. /* Global vars for SCSI control */
  71. IOSTDREQ *ioreq;
  72. MSGPORT *msgport;
  73. UBYTE *scsidata;
  74. SCSICMD *scsicmd;
  75. UBYTE *scsisense;
  76.  
  77. UBYTE scsidev[256]="scsi.device";
  78. int scsiid=4;
  79. BOOL volumecontrol=TRUE;
  80.  
  81. /* For the logo */
  82. static struct BitMap logobm=
  83. {
  84.     30,
  85.     30,
  86.     0,
  87.     2,
  88.     PAD,
  89.     (UBYTE *)logoplane0,
  90.     (UBYTE *)logoplane1,
  91.     NULL,NULL,NULL,NULL,NULL,NULL
  92. };
  93.  
  94. const ULONG logocolours[]=
  95. {
  96.     0xc0c0c0c0, 0xc0c0c0c0, 0xc0c0c0c0,
  97.     0x00000000, 0x00000000, 0x00000000,
  98.     0xffffffff, 0xffffffff, 0xffffffff,
  99.     0x46464646, 0x7c7c7c7c, 0xbbbbbbbb
  100. };
  101.  
  102. /* For the menu */
  103. static struct NewMenu menudata[]=
  104. {
  105.     { NM_TITLE, NULL,           0, 0, 0,    (APTR)MEN_PROJECT   },
  106.     { NM_ITEM,  NULL,           0, 0, 0,    (APTR)MEN_ABOUT     },
  107.     { NM_ITEM,  NULL,           0, 0, 0,    (APTR)MEN_ABOUTMUI  },
  108.     { NM_ITEM,  NM_BARLABEL,    0, 0, 0,    (APTR)0             },
  109.     { NM_ITEM,  NULL,           0, 0, 0,    (APTR)MEN_QUIT      },
  110.     { NM_TITLE, NULL,           0, 0, 0,    (APTR)MEN_SETTINGS  },
  111.     { NM_ITEM,  NULL,           0, 0, 0,    (APTR)MEN_MUI       },
  112.     { NM_END,NULL,0,0,0,(APTR)0 },
  113. };
  114.  
  115. static APTR AP_SCDP=NULL;
  116. static APTR WI_SCDP,WI_List,WI_Program;
  117. static APTR TX_Track,TX_TitleTime,TX_CDTime,TX_Artist,TX_Title;
  118. static APTR BT_Play,BT_Pause,BT_Stop,BT_Previous,BT_Next,BT_Rewind,BT_FastForward,BT_Eject,BT_Shuffle,BT_ProgramL,BT_Repeat;
  119. static APTR BT_ProgramR,BT_List;
  120. static APTR SL_Volume;
  121. static APTR ST_Artist,ST_CDTitle,ST_Title,LV_TrackSelect,LV_TitleList,BT_Use,BT_Save,BT_Cancel;
  122. static APTR LV_PList,LI_PList,LV_Program,BT_PUse,BT_PSave,BT_PCancel,BT_PNew,BT_PDelete,BT_PUp,BT_PDown,BT_PTop,BT_PBottom;
  123. static APTR MN_Menu, WI_AboutMUI=NULL;
  124.  
  125. struct TextFont *getfont(char *name)
  126. {
  127.     char buff[100];
  128.     int i;
  129.     struct TextAttr ta;
  130.  
  131.     i=0;
  132.     while((buff[i]=name[i])!='/' && buff[i]!='\0')
  133.         i++;
  134.  
  135.     if(!buff[i])
  136.         return NULL;
  137.  
  138.     buff[i]='\0';
  139.     strcat(buff,".font");
  140.  
  141.     ta.ta_Name=buff;
  142.     ta.ta_YSize=atoi(name+i+1);
  143.     ta.ta_Style=0;
  144.     ta.ta_Flags=0;
  145.  
  146.     return OpenDiskFont(&ta);
  147. }
  148.  
  149. /* I will try here to program some drag&drop for program window */
  150. /* See DragnDrop.c in MUI examples */
  151. struct ProgramList_Data
  152. {
  153.     LONG dummy;
  154. };
  155.  
  156. ULONG ProgramList_DragQuery(struct IClass *cl, Object *obj, struct MUIP_DragDrop *msg)
  157. {
  158.     if(msg->obj==obj)
  159.         return(DoSuperMethodA(cl,obj,msg));
  160.     else if(msg->obj==(Object *)LI_PList) /* Hard coded source list */
  161.         return(MUIV_DragQuery_Accept);
  162.     else
  163.         return(MUIV_DragQuery_Refuse);
  164. }
  165.  
  166. ULONG ProgramList_DragDrop(struct IClass *cl, Object *obj, struct MUIP_DragDrop *msg)
  167. {
  168.     if(msg->obj==obj)
  169.         return(DoSuperMethodA(cl,obj,msg));
  170.     else
  171.     {
  172.         char *entry;
  173.         LONG dropmark;
  174.  
  175.         DoMethod(msg->obj,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&entry);
  176.  
  177.         get(obj,MUIA_List_DropMark,&dropmark);
  178.         DoMethod(obj,MUIM_List_InsertSingle,entry,dropmark);
  179.  
  180.         get(obj,MUIA_List_InsertPosition,&dropmark);
  181.         set(obj,MUIA_List_Active,dropmark);
  182.         set(msg->obj,MUIA_List_Active,MUIV_List_Active_Off);
  183.  
  184.         return 0;
  185.     }
  186. }
  187.  
  188. SAVEDS ASM ULONG ProgramList_Dispatcher(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
  189. {
  190.     switch(msg->MethodID)
  191.     {
  192.         case MUIM_DragQuery:    return ProgramList_DragQuery(cl,obj,(APTR)msg);
  193.         case MUIM_DragDrop:     return ProgramList_DragDrop(cl,obj,(APTR)msg);
  194.     }
  195.     return DoSuperMethodA(cl,obj,msg);
  196. }
  197.  
  198. /* Main program at last */
  199. int main(int argc, char *argv[])
  200. {
  201.     char *errorstr=NULL;
  202.     int i,vamos,a,b;
  203.     ULONG signals;
  204.     char buff[256];
  205.     UBYTE *strptr=NULL;
  206.     struct DiskObject *mydo;
  207.     FILE *f;
  208.  
  209.     if(stacksize()<STACKSIZE)
  210.         fail(NULL,glstr(MSG_FailStack));
  211.  
  212.     if(argc==0)
  213.     {
  214.         argc=_WBArgc;
  215.         argv=_WBArgv;
  216.     }
  217.  
  218.     i=strlen(argv[0]);
  219.     while(argv[0][i]!='/' && argv[0][i]!=':' && i)
  220.         i--;
  221.  
  222.     if(argv[0][i]=='/' || argv[0][i]==':')
  223.         sprintf(buff,"PROGDIR:%s",argv[0]+i+1);
  224.     else
  225.         sprintf(buff,"PROGDIR:%s",argv[0]);
  226.  
  227.     init();
  228.  
  229.     mydo=GetDiskObject(buff);
  230.  
  231.     for(a=1;a<argc;a++)
  232.     {
  233.         if(!strncmp(argv[a],"DEVICE=",7))
  234.             strcpy(scsidev,argv[a]+7);
  235.         if(!strncmp(argv[a],"UNIT=",5))
  236.             scsiid=atoi(argv[a]+5);
  237.         if(!strcmp(argv[a],"NOVOLUME"))
  238.             volumecontrol=FALSE;
  239.         if(!strcmp(argv[a],"CUSTOMFONTS"))
  240.             customfonts=TRUE;
  241.         if(!strncmp(argv[a],"NORMALFONT=",11))
  242.             normalname=argv[a]+11;
  243.         if(!strncmp(argv[a],"TINYFONT=",9))
  244.             tinyname=argv[a]+9;
  245.         if(!strncmp(argv[a],"FIXEDFONT=",10))
  246.             fixedname=argv[a]+10;
  247.         if(!strncmp(argv[a],"LISTFONT=",9))
  248.             listname=argv[a]+9;
  249.         if(!strncmp(argv[a],"TITLEFONT=",10))
  250.             titlename=argv[a]+10;
  251.     }
  252.  
  253.     if(customfonts)
  254.     {
  255.         normalfont=getfont(normalname);
  256.         tinyfont=getfont(tinyname);
  257.         fixedfont=getfont(fixedname);
  258.         listfont=getfont(listname);
  259.         titlefont=getfont(titlename);
  260.  
  261.         if(!normalfont || !tinyfont || !fixedfont || !listfont || !titlefont)
  262.             fail(NULL,glstr(MSG_FailNoFont));
  263.     }
  264.  
  265.     if(msgport=CreateMsgPort())
  266.     {
  267.         if(ioreq=CreateIORequest(msgport,sizeof(IOSTDREQ)))
  268.         {
  269.             if(!(OpenDevice(scsidev,scsiid,(struct IORequest *)ioreq,0)))
  270.             {
  271.                 if(scsicmd=AllocMem(sizeof(SCSICMD), MEMF_CHIP|MEMF_CLEAR|MEMF_PUBLIC))
  272.                 {
  273.                     if(scsisense=AllocMem(SENSE_LEN, MEMF_CHIP|MEMF_CLEAR|MEMF_PUBLIC))
  274.                     {
  275.                         if(tmsgport=CreateMsgPort())
  276.                         {
  277.                             if(tioreq=CreateIORequest(tmsgport,sizeof(struct timerequest)))
  278.                             {
  279.                                 if(!(OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)tioreq,0)))
  280.                                 {
  281.                                     if(scsidata=AllocMem(MAX_DATA_LEN,MEMF_CHIP|MEMF_CLEAR|MEMF_PUBLIC))
  282.                                     {
  283.                                         if(TOCbuf=AllocMem(MAX_TOC_LEN,MEMF_CHIP|MEMF_PUBLIC))
  284.                                         {
  285.                                             programmed[0]=0;
  286.  
  287.                                             menudata[0].nm_Label=glstr(MSG_MenuProject);
  288.                                             menudata[1].nm_Label=glstr(MSG_MenuAbout);
  289.                                             menudata[1].nm_CommKey=glstr(MSG_MenuAboutKey);
  290.                                             menudata[2].nm_Label=glstr(MSG_MenuAboutMUI);
  291.                                             menudata[4].nm_Label=glstr(MSG_MenuQuit);
  292.                                             menudata[4].nm_CommKey=glstr(MSG_MenuQuitKey);
  293.                                             menudata[5].nm_Label=glstr(MSG_MenuSettings);
  294.                                             menudata[6].nm_Label=glstr(MSG_MenuMUI);
  295.  
  296.                                             CL_ProgramList=MUI_CreateCustomClass(NULL,MUIC_List,NULL,sizeof(struct ProgramList_Data),ProgramList_Dispatcher);
  297.  
  298.                                             if(CL_ProgramList)
  299.                                             {
  300.                                                 AP_SCDP = ApplicationObject,
  301.                                                     MUIA_Application_Title,         "SCDPlayer",
  302.                                                     MUIA_Application_Version,       "$VER: SCDPlayer " VERSION " (" __DATE__ " " __TIME__ ")",
  303.                                                     MUIA_Application_Copyright,     "Copyright ©1996, Juan J. García de Soria",
  304.                                                     MUIA_Application_Author,        "Juan J. García de Soria",
  305.                                                     MUIA_Application_Description,   glstr(MSG_SCDPDescription),
  306.                                                     MUIA_Application_Base,          "SCDP",
  307.                                                     MUIA_Application_DiskObject,    mydo,
  308.                                                     MUIA_Application_Menustrip,MN_Menu=MUI_MakeObject(MUIO_MenustripNM,menudata,0),
  309.                                                     SubWindow,
  310.                                                         WI_SCDP=WindowObject,
  311.                                                         MUIA_Window_Title, "SCDPlayer " VERSION,
  312.                                                         MUIA_Window_ID,MAKE_ID('S','C','D','P'),
  313.                                                         WindowContents,HGroup,
  314.                                                             MUIA_Background,MUII_WindowBack,
  315.                                                             MUIA_Font,(customfonts)?(ULONG)normalfont:MUIV_Font_Normal,
  316.                                                             Child,VGroup,   /* Lado izquierdo de la ventana */
  317.                                                                 MUIA_Background,MUII_WindowBack,
  318.                                                                 MUIA_Weight,1,
  319.                                                                 Child,VGroup,
  320.                                                                     MUIA_VertDisappear,1,
  321.                                                                     MUIA_Background,MUII_TextBack,
  322.                                                                     MUIA_Weight,70,
  323.                                                                     TextFrame,
  324.                                                                     Child,VSpace(0),
  325.                                                                     Child,HGroup,
  326.                                                                         Child,HSpace(0),
  327.                                                                         Child,BitmapObject,
  328.                                                                             MUIA_FixWidth,232,
  329.                                                                             MUIA_FixHeight,30,
  330.                                                                             MUIA_Bitmap_Bitmap,&logobm,
  331.                                                                             MUIA_Bitmap_Transparent,0,
  332.                                                                             MUIA_Bitmap_Width,232,
  333.                                                                             MUIA_Bitmap_Height,30,
  334.                                                                             MUIA_Bitmap_SourceColors,logocolours,
  335.                                                                             End,
  336.                                                                         Child,HSpace(0),
  337.                                                                         End,
  338.                                                                     Child,VSpace(0),
  339.                                                                     End,
  340.                                                                 Child,VGroup,   /* Zona de estado */
  341.                                                                     MUIA_VertDisappear,2,
  342.                                                                     MUIA_Background,MUII_TextBack,
  343.                                                                     GroupFrame,
  344.                                                                     MUIA_ShortHelp,glstr(MSG_HelpInfo),
  345.                                                                     Child,VSpace(0),
  346.                                                                     Child,HGroup,   /* Los tres indicadores */
  347.                                                                         Child,VGroup,   /* Nº de pista */
  348.                                                                             MUIA_Weight,0,
  349.                                                                             Child,TextObject,
  350.                                                                                 MUIA_Font,(customfonts)?(ULONG)tinyfont:MUIV_Font_Tiny,
  351.                                                                                 MUIA_Text_Contents,glstr(MSG_Track),
  352.                                                                                 MUIA_Text_PreParse,"\33l",
  353.                                                                                 End,
  354.                                                                             Child,TX_Track=TextObject,
  355.                                                                                 MUIA_Font,(customfonts)?(ULONG)fixedfont:MUIV_Font_Fixed,
  356.                                                                                 MUIA_Text_Contents,"--",
  357.                                                                                 MUIA_Text_PreParse,"\33l",
  358.                                                                                 End,
  359.                                                                             End,
  360.                                                                         Child,HSpace(0),
  361.                                                                         Child,VGroup,   /* Posición en pista actual */
  362.                                                                             MUIA_Weight,0,
  363.                                                                             Child,TextObject,
  364.                                                                                 MUIA_Font,(customfonts)?(ULONG)tinyfont:MUIV_Font_Tiny,
  365.                                                                                 MUIA_Text_Contents,glstr(MSG_TitleTime),
  366.                                                                                 MUIA_Text_PreParse,"\33l",
  367.                                                                                 End,
  368.                                                                             Child,TX_TitleTime=TextObject,
  369.                                                                                 MUIA_Font,(customfonts)?(ULONG)fixedfont:MUIV_Font_Fixed,
  370.                                                                                 MUIA_Text_Contents,"--:--/--:--",
  371.                                                                                 MUIA_Text_PreParse,"\33l",
  372.                                                                                 End,
  373.                                                                             End,
  374.                                                                         Child,HSpace(0),
  375.                                                                         Child,VGroup,   /* Posición en todo el CD */
  376.                                                                             MUIA_Weight,0,
  377.                                                                             Child,TextObject,
  378.                                                                                 MUIA_Font,(customfonts)?(ULONG)tinyfont:MUIV_Font_Tiny,
  379.                                                                                 MUIA_Text_Contents,glstr(MSG_CDTime),
  380.                                                                                 MUIA_Text_PreParse,"\33l",
  381.                                                                                 End,
  382.                                                                             Child,TX_CDTime=TextObject,
  383.                                                                                 MUIA_Font,(customfonts)?(ULONG)fixedfont:MUIV_Font_Fixed,
  384.                                                                                 MUIA_Text_Contents,"--:--/--:--",
  385.                                                                                 MUIA_Text_PreParse,"\33l",
  386.                                                                                 End,
  387.                                                                             End,
  388.                                                                         End,
  389.                                                                     Child,TX_Artist=TextObject,
  390.                                                                         MUIA_Font,(customfonts)?(ULONG)normalfont:MUIV_Font_Normal,
  391.                                                                         MUIA_Text_SetMin,FALSE,
  392.                                                                         MUIA_Text_Contents,glstr(MSG_NoDisc),
  393.                                                                         MUIA_Text_PreParse,"\33l",
  394.                                                                         End,
  395.                                                                     Child,TX_Title=TextObject,
  396.                                                                         MUIA_Text_SetMin,FALSE,
  397.                                                                         MUIA_Font,(customfonts)?(ULONG)normalfont:MUIV_Font_Normal,
  398.                                                                         MUIA_Text_Contents,"",
  399.                                                                         MUIA_Text_PreParse,"\33l",
  400.                                                                         End,
  401.                                                                     Child,VSpace(0),
  402.                                                                     End,
  403.                                                                 Child,HGroup,
  404.                                                                     MUIA_Background,MUII_GroupBack,
  405.                                                                     GroupFrame,
  406.                                                                     Child,HSpace(0),
  407.                                                                     Child,VGroup,
  408.                                                                         Child,VSpace(0),
  409.                                                                         Child,HGroup,
  410.                                                                             MUIA_Weight,0,
  411.                                                                             Child,BT_Play=MyImageButton("Play",' ',MSG_HelpPlay),
  412.                                                                             Child,BT_Pause=MyImageButton("Pause",'.',MSG_HelpPause),
  413.                                                                             Child,BT_Stop=MyImageButton("Stop",'s',MSG_HelpStop),
  414.                                                                             Child,BT_Previous=MyImageButton("Previous",'p',MSG_HelpPrevious),
  415.                                                                             Child,BT_Next=MyImageButton("Next",'n',MSG_HelpNext),
  416.                                                                             Child,BT_Rewind=MyImageButton("Rewind",'r',MSG_HelpRewind),
  417.                                                                             Child,BT_FastForward=MyImageButton("FastForward",'f',MSG_HelpFastForward),
  418.                                                                             Child,BT_Eject=MyImageButton("Eject",'e',MSG_HelpEject),
  419.                                                                             End,
  420.                                                                         Child,HGroup,
  421.                                                                             Child,MyImage("VolumeLow"),
  422.                                                                             Child,SL_Volume=SliderObject,
  423.                                                                                 MUIA_ShortHelp,glstr(MSG_HelpVolume),
  424.                                                                                 MUIA_Slider_Min,1,
  425.                                                                                 MUIA_Slider_Max,31,
  426.                                                                                 MUIA_Slider_Level,16,
  427.                                                                                 MUIA_Slider_Quiet,TRUE,
  428.                                                                                 End,
  429.                                                                             Child,MyImage("VolumeHigh"),
  430.                                                                             Child,BT_ProgramL=MyImageButton2("Program",'o',MSG_HelpProgramL),
  431.                                                                             Child,BT_Shuffle=MyImageButton2("Shuffle",'q',MSG_HelpShuffle),
  432.                                                                             Child,BT_Repeat=MyImageButton2("Repeat",'a',MSG_HelpRepeat),
  433.                                                                             End,
  434.                                                                         Child,VSpace(0),
  435.                                                                         End,
  436.                                                                     Child,HSpace(0),
  437.                                                                     End,
  438.                                                                 End,
  439.                                                             Child,VGroup,   /* Lado derecho de la ventana */
  440.                                                                 MUIA_HorizDisappear,1,
  441.                                                                 MUIA_Background,MUII_GroupBack,
  442.                                                                 GroupFrame,
  443.                                                                 MUIA_Weight,99,
  444.                                                                 Child,LV_TrackSelect=ListviewObject,
  445.                                                                     MUIA_ShortHelp,glstr(MSG_HelpTrackSelect),
  446.                                                                     MUIA_Listview_List,ListObject,
  447.                                                                         ReadListFrame,
  448.                                                                         MUIA_Font,(customfonts)?(ULONG)listfont:MUIV_Font_List,
  449.                                                                         MUIA_List_ConstructHook,MUIV_List_ConstructHook_String,
  450.                                                                         MUIA_List_DestructHook,MUIV_List_DestructHook_String,
  451.                                                                         MUIA_Background,MUII_ListBack,
  452.                                                                         End,
  453.                                                                     End,
  454.                                                                 Child,HGroup,
  455.                                                                     MUIA_VertDisappear,1,
  456.                                                                     Child,BT_List=SimpleButton(glstr(MSG_ListButton)),
  457.                                                                     Child,BT_ProgramR=SimpleButton(glstr(MSG_ProgramButton)),
  458.                                                                     End,
  459.                                                                 End,
  460.                                                             End,
  461.                                                         End,
  462.                                                     SubWindow,
  463.                                                         WI_List=WindowObject,
  464.                                                         MUIA_Window_Title, glstr(MSG_CDInformation),
  465.                                                         MUIA_Window_ID,MAKE_ID('L','I','S','T'),
  466.                                                         WindowContents,VGroup,
  467.                                                             MUIA_Background,MUII_WindowBack,
  468.                                                             MUIA_Font,(customfonts)?(ULONG)normalfont:MUIV_Font_Normal,
  469.                                                             Child,ColGroup(2),
  470.                                                                 Child,Label2(glstr(MSG_Artist)),
  471.                                                                 Child,ST_Artist=StringObject,
  472.                                                                     StringFrame,
  473.                                                                     MUIA_ShortHelp,glstr(MSG_HelpArtist),
  474.                                                                     MUIA_String_MaxLen,127,
  475.                                                                     End,
  476.                                                                 Child,Label2(glstr(MSG_CDTitle)),
  477.                                                                 Child,ST_CDTitle=StringObject,
  478.                                                                     StringFrame,
  479.                                                                     MUIA_ShortHelp,glstr(MSG_HelpCDTitle),
  480.                                                                     MUIA_String_MaxLen,127,
  481.                                                                     End,
  482.                                                                 End,
  483.                                                             Child,TextObject,
  484.                                                                 MUIA_Font,(customfonts)?(ULONG)titlefont:MUIV_Font_Title,
  485.                                                                 MUIA_Text_Contents,glstr(MSG_TitleList),
  486.                                                                 MUIA_Text_PreParse,"\33c",
  487.                                                                 End,
  488.                                                             Child,LV_TitleList=ListviewObject,
  489.                                                                 MUIA_Listview_List,ListObject,
  490.                                                                     MUIA_Font,(customfonts)?(ULONG)listfont:MUIV_Font_List,
  491.                                                                     MUIA_ShortHelp,glstr(MSG_HelpTitles),
  492.                                                                     InputListFrame,
  493.                                                                     MUIA_List_ConstructHook,MUIV_List_ConstructHook_String,
  494.                                                                     MUIA_List_DestructHook,MUIV_List_DestructHook_String,
  495.                                                                     MUIA_Background,MUII_ListBack,
  496.                                                                     End,
  497.                                                                 End,
  498.                                                             Child,ST_Title=StringObject,
  499.                                                                 StringFrame,
  500.                                                                 MUIA_ShortHelp,glstr(MSG_HelpTitle),
  501.                                                                 MUIA_String_MaxLen,127,
  502.                                                                 MUIA_String_AttachedList,LV_TitleList,
  503.                                                                 End,
  504.                                                             Child,HGroup,
  505.                                                                 Child,BT_Use=SimpleButton(glstr(MSG_Use)),
  506.                                                                 Child,BT_Save=SimpleButton(glstr(MSG_Save)),
  507.                                                                 Child,BT_Cancel=SimpleButton(glstr(MSG_Cancel)),
  508.                                                                 End,
  509.                                                             End,
  510.                                                         End,
  511.                                                     SubWindow,
  512.                                                         WI_Program=WindowObject,
  513.                                                         MUIA_Window_Title,glstr(MSG_ProgramWindowTitle),
  514.                                                         MUIA_Window_ID,MAKE_ID('P','R','O','G'),
  515.                                                         WindowContents,VGroup,
  516.                                                             MUIA_Font,(customfonts)?(ULONG)normalfont:MUIV_Font_Normal,
  517.                                                             MUIA_Background,MUII_WindowBack,
  518.                                                             Child,HGroup,
  519.                                                                 Child,VGroup,
  520.                                                                     Child,TextObject,
  521.                                                                         MUIA_Font,(customfonts)?(ULONG)titlefont:MUIV_Font_Title,
  522.                                                                         MUIA_Text_Contents,glstr(MSG_TitleList),
  523.                                                                         MUIA_Text_PreParse,"\33c",
  524.                                                                         End,
  525.                                                                     Child,LV_PList=ListviewObject,
  526.                                                                         MUIA_Listview_DragType,MUIV_Listview_DragType_Immediate,
  527.                                                                         MUIA_Listview_List,LI_PList=ListObject,
  528.                                                                             MUIA_Font,(customfonts)?(ULONG)listfont:MUIV_Font_List,
  529.                                                                             InputListFrame,
  530.                                                                             MUIA_ShortHelp,glstr(MSG_HelpPTitles),
  531.                                                                             MUIA_List_ConstructHook,MUIV_List_ConstructHook_String,
  532.                                                                             MUIA_List_DestructHook,MUIV_List_DestructHook_String,
  533.                                                                             MUIA_Background,MUII_ListBack,
  534.                                                                             End,
  535.                                                                         End,
  536.                                                                     End,
  537.                                                                 Child,VGroup,
  538.                                                                     MUIA_Weight,0,
  539.                                                                     Child,VSpace(0),
  540.                                                                     Child,BT_PNew=SimpleButton(glstr(MSG_New)),
  541.                                                                     Child,BT_PDelete=SimpleButton(glstr(MSG_Delete)),
  542.                                                                     Child,BT_PTop=SimpleButton(glstr(MSG_Top)),
  543.                                                                     Child,BT_PUp=SimpleButton(glstr(MSG_Up)),
  544.                                                                     Child,BT_PDown=SimpleButton(glstr(MSG_Down)),
  545.                                                                     Child,BT_PBottom=SimpleButton(glstr(MSG_Bottom)),
  546.                                                                     Child,VSpace(0),
  547.                                                                     End,
  548.                                                                 Child,VGroup,
  549.                                                                     Child,TextObject,
  550.                                                                         MUIA_Font,(customfonts)?(ULONG)titlefont:MUIV_Font_Title,
  551.                                                                         MUIA_Text_Contents,glstr(MSG_ProgramList),
  552.                                                                         MUIA_Text_PreParse,"\33c",
  553.                                                                         End,
  554.                                                                     Child,LV_Program=ListviewObject,
  555.                                                                         MUIA_Listview_DragType,MUIV_Listview_DragType_Immediate,
  556.                                                                         MUIA_Listview_List,NewObject(CL_ProgramList->mcc_Class,NULL,
  557.                                                                             MUIA_Font,(customfonts)?(ULONG)listfont:MUIV_Font_List,
  558.                                                                             InputListFrame,
  559.                                                                             MUIA_List_DragSortable,TRUE,
  560.                                                                             MUIA_ShortHelp,glstr(MSG_HelpProgramList),
  561.                                                                             MUIA_List_ConstructHook,MUIV_List_ConstructHook_String,
  562.                                                                             MUIA_List_DestructHook,MUIV_List_DestructHook_String,
  563.                                                                             MUIA_Background,MUII_ListBack,
  564.                                                                             TAG_DONE),
  565.                                                                         End,
  566.                                                                     End,
  567.                                                                 End,
  568.                                                             Child,HGroup,
  569.                                                                 Child,BT_PUse=SimpleButton(glstr(MSG_Use)),
  570.                                                                 Child,BT_PSave=SimpleButton(glstr(MSG_Save)),
  571.                                                                 Child,BT_PCancel=SimpleButton(glstr(MSG_Cancel)),
  572.                                                                 End,
  573.                                                             End,
  574.                                                         End,
  575.                                                     End;
  576.                                             }
  577.  
  578.                                             if(AP_SCDP)
  579.                                             {
  580.                                                 set(BT_ProgramR,MUIA_ShortHelp,glstr(MSG_HelpProgramR));
  581.                                                 set(BT_List,MUIA_ShortHelp,glstr(MSG_HelpList));
  582.                                                 set(BT_Use,MUIA_ShortHelp,glstr(MSG_HelpUse));
  583.                                                 set(BT_Save,MUIA_ShortHelp,glstr(MSG_HelpSave));
  584.                                                 set(BT_Cancel,MUIA_ShortHelp,glstr(MSG_HelpCancel));
  585.                                                 set(BT_PUse,MUIA_ShortHelp,glstr(MSG_HelpUse));
  586.                                                 set(BT_PSave,MUIA_ShortHelp,glstr(MSG_HelpSave));
  587.                                                 set(BT_PCancel,MUIA_ShortHelp,glstr(MSG_HelpCancel));
  588.                                                 set(BT_PNew,MUIA_ShortHelp,glstr(MSG_HelpNew));
  589.                                                 set(BT_PDelete,MUIA_ShortHelp,glstr(MSG_HelpDelete));
  590.                                                 set(BT_PTop,MUIA_ShortHelp,glstr(MSG_HelpTop));
  591.                                                 set(BT_PUp,MUIA_ShortHelp,glstr(MSG_HelpUp));
  592.                                                 set(BT_PDown,MUIA_ShortHelp,glstr(MSG_HelpDown));
  593.                                                 set(BT_PBottom,MUIA_ShortHelp,glstr(MSG_HelpBottom));
  594.  
  595.                                                 DoMethod(WI_SCDP,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,AP_SCDP,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);
  596.                                                 DoMethod(WI_List,MUIM_Window_SetCycleChain,ST_Artist,ST_CDTitle,ST_Title,BT_Use,BT_Save,BT_Cancel,NULL);
  597.                                                 DoMethod(WI_Program,MUIM_Window_SetCycleChain,LV_PList,BT_PNew,BT_PDelete,BT_PTop,BT_PUp,BT_PDown,BT_PBottom,LV_Program,BT_PUse,BT_PSave,BT_PCancel,NULL);
  598.  
  599.                                                 DoMethod(BT_Shuffle,MUIM_Notify,MUIA_Selected,TRUE,BT_ProgramL,3,MUIM_Set,MUIA_Selected,FALSE);
  600.                                                 DoMethod(BT_ProgramL,MUIM_Notify,MUIA_Selected,TRUE,BT_Shuffle,3,MUIM_Set,MUIA_Selected,FALSE);
  601.  
  602.                                                 DoMethod(BT_List,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_List);
  603.                                                 DoMethod(BT_ProgramR,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_ProgramR);
  604.                                                 DoMethod(BT_Play,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_Play);
  605.                                                 DoMethod(BT_Pause,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_Pause);
  606.                                                 DoMethod(BT_Stop,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_Stop);
  607.                                                 DoMethod(BT_Previous,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_Previous);
  608.                                                 DoMethod(BT_Next,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_Next);
  609.                                                 DoMethod(BT_Rewind,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_Rewind);
  610.                                                 DoMethod(BT_FastForward,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_FastForward);
  611.                                                 DoMethod(BT_Eject,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_Eject);
  612.                                                 DoMethod(BT_ProgramL,MUIM_Notify,MUIA_Selected,MUIV_EveryTime,AP_SCDP,2,MUIM_Application_ReturnID,ID_ProgramL);
  613.                                                 DoMethod(BT_Shuffle,MUIM_Notify,MUIA_Selected,MUIV_EveryTime,AP_SCDP,2,MUIM_Application_ReturnID,ID_Shuffle);
  614.                                                 DoMethod(SL_Volume,MUIM_Notify,MUIA_Slider_Level,MUIV_EveryTime,AP_SCDP,2,MUIM_Application_ReturnID,ID_Volume);
  615.  
  616.                                                 DoMethod(BT_Use,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_Use);
  617.                                                 DoMethod(BT_Save,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_Save);
  618.                                                 DoMethod(BT_Cancel,MUIM_Notify,MUIA_Selected,FALSE,WI_List,3,MUIM_Set,MUIA_Window_Open,FALSE);
  619.                                                 DoMethod(WI_List,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,WI_List,3,MUIM_Set,MUIA_Window_Open,FALSE);
  620.  
  621.                                                 DoMethod(LV_TrackSelect,MUIM_Notify,MUIA_Listview_DoubleClick,TRUE,AP_SCDP,2,MUIM_Application_ReturnID,ID_TrackSelect);
  622.                                                 DoMethod(LV_TitleList,MUIM_Notify,MUIA_List_Active,MUIV_EveryTime,AP_SCDP,2,MUIM_Application_ReturnID,ID_ChangeActive);
  623.                                                 DoMethod(ST_Title,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,AP_SCDP,2,MUIM_Application_ReturnID,ID_Confirm);
  624.                                                 DoMethod(ST_Title,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,WI_List,3,MUIM_Set,MUIA_Window_ActiveObject,ST_Title);
  625.                                                 DoMethod(ST_Artist,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,WI_List,3,MUIM_Set,MUIA_Window_ActiveObject,ST_CDTitle);
  626.                                                 DoMethod(ST_CDTitle,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,WI_List,3,MUIM_Set,MUIA_Window_ActiveObject,ST_Title);
  627.  
  628.                                                 DoMethod(BT_PUse,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_PUse);
  629.                                                 DoMethod(BT_PSave,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_PSave);
  630.                                                 DoMethod(BT_PCancel,MUIM_Notify,MUIA_Selected,FALSE,WI_Program,3,MUIM_Set,MUIA_Window_Open,FALSE);
  631.                                                 DoMethod(WI_Program,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,WI_Program,3,MUIM_Set,MUIA_Window_Open,FALSE);
  632.                                                 DoMethod(LV_PList,MUIM_Notify,MUIA_Listview_DoubleClick,MUIV_EveryTime,AP_SCDP,2,MUIM_Application_ReturnID,ID_PInsert);
  633.                                                 DoMethod(BT_PNew,MUIM_Notify,MUIA_Selected,FALSE,LV_Program,1,MUIM_List_Clear);
  634.                                                 DoMethod(BT_PDelete,MUIM_Notify,MUIA_Selected,FALSE,LV_Program,2,MUIM_List_Remove,MUIV_List_Remove_Active);
  635.                                                 DoMethod(BT_PTop,MUIM_Notify,MUIA_Selected,FALSE,LV_Program,3,MUIM_List_Move,MUIV_List_Move_Active,MUIV_List_Move_Top);
  636.                                                 DoMethod(BT_PTop,MUIM_Notify,MUIA_Selected,FALSE,LV_Program,3,MUIM_Set,MUIA_List_Active,MUIV_List_Active_Top);
  637.                                                 DoMethod(BT_PUp,MUIM_Notify,MUIA_Selected,FALSE,LV_Program,3,MUIM_List_Move,MUIV_List_Move_Active,MUIV_List_Move_Previous);
  638.                                                 DoMethod(BT_PUp,MUIM_Notify,MUIA_Selected,FALSE,LV_Program,3,MUIM_Set,MUIA_List_Active,MUIV_List_Active_Up);
  639.                                                 DoMethod(BT_PDown,MUIM_Notify,MUIA_Selected,FALSE,LV_Program,3,MUIM_List_Move,MUIV_List_Move_Active,MUIV_List_Move_Next);
  640.                                                 DoMethod(BT_PDown,MUIM_Notify,MUIA_Selected,FALSE,LV_Program,3,MUIM_Set,MUIA_List_Active,MUIV_List_Active_Down);
  641.                                                 DoMethod(BT_PBottom,MUIM_Notify,MUIA_Selected,FALSE,LV_Program,3,MUIM_List_Move,MUIV_List_Move_Active,MUIV_List_Move_Bottom);
  642.                                                 DoMethod(BT_PBottom,MUIM_Notify,MUIA_Selected,FALSE,LV_Program,3,MUIM_Set,MUIA_List_Active,MUIV_List_Active_Bottom);
  643.                                                 DoMethod(LV_Program,MUIM_Notify,MUIA_Listview_DoubleClick,MUIV_EveryTime,LV_Program,2,MUIM_List_Remove,MUIV_List_Remove_Active);
  644.  
  645.                                                 set(BT_List,MUIA_Disabled,TRUE);
  646.                                                 set(BT_ProgramR,MUIA_Disabled,TRUE);
  647.                                                 set(WI_SCDP,MUIA_Window_Open,TRUE);
  648.  
  649.                                                 if(!volumecontrol)
  650.                                                     set(SL_Volume,MUIA_Disabled,TRUE);
  651.  
  652.                                                 /*set(WI_Program,MUIA_Window_Open,TRUE);*/
  653.  
  654.                                                 i=vamos=TRUE;
  655.                                                 signals=0;
  656.                                                 CDSetVolume(-1);
  657.  
  658.                                                 while(i)
  659.                                                 {
  660.                                                     if(signals&(1<<tmsgport->mp_SigBit))
  661.                                                     {
  662.                                                         GetMsg(tmsgport);
  663.                                                         if(actuate)
  664.                                                         {
  665.                                                             get(BT_Repeat,MUIA_Selected,&a);
  666.                                                             if(pstatus==NORMAL)
  667.                                                             {
  668.                                                                 if(a)
  669.                                                                 {
  670.                                                                     track=1;
  671.                                                                     while((TOCflags[track-1]&1) && track<=TOClength)
  672.                                                                         track++;
  673.                                                                     if(track>TOClength)
  674.                                                                     {
  675.                                                                         CDStop();
  676.                                                                         track=0;
  677.                                                                     }
  678.                                                                     else
  679.                                                                     {
  680.                                                                         CDPlay(TOCaddr[track-1],TOCaddr[TOClength]-TOCaddr[track-1]);
  681.                                                                         CDGetPos(FALSE);
  682.                                                                     }
  683.                                                                 }
  684.                                                                 else
  685.                                                                 {
  686.                                                                     CDStop();
  687.                                                                     track=0;
  688.                                                                 }
  689.                                                             }
  690.                                                             else
  691.                                                             {
  692.                                                                 pactual++;
  693.                                                                 if(!programmed[pactual-1] && a)
  694.                                                                 {
  695.                                                                     pactual=1;
  696.                                                                     if(pstatus==SHUFFLE)
  697.                                                                         DoShuffle();
  698.                                                                 }
  699.                                                                 if(!programmed[pactual-1])
  700.                                                                 {
  701.                                                                     CDStop();
  702.                                                                     track=0;
  703.                                                                 }
  704.                                                                 else
  705.                                                                 {
  706.                                                                     track=programmed[pactual-1];
  707.                                                                     CDPlay(TOCaddr[track-1],TOCaddr[TOClength]-TOCaddr[track-1]);
  708.                                                                 }
  709.                                                             }
  710.                                                             actuate=0;
  711.                                                         }
  712.  
  713.                                                         CDGetPos(TRUE);
  714.                                                     }
  715.  
  716.                                                     b=DoMethod(AP_SCDP,MUIM_Application_Input,&signals);
  717.                                                     if((b==ID_Next || b==ID_Previous) && status!=PLAYING)
  718.                                                         b=ID_Play;
  719.                                                     switch(b)
  720.                                                     {
  721.                                                         case MEN_QUIT:
  722.                                                         case MUIV_Application_ReturnID_Quit:
  723.                                                             i=FALSE;
  724.                                                             break;
  725.                                                         case MEN_ABOUT:
  726.                                                             MUI_Request(AP_SCDP,WI_SCDP,0,NULL,glstr(MSG_AboutGadget),glstr(MSG_AboutText));
  727.                                                             break;
  728.                                                         case MEN_ABOUTMUI:
  729.                                                             if(!WI_AboutMUI)
  730.                                                                 WI_AboutMUI=AboutmuiObject,
  731.                                                                     MUIA_Window_RefWindow,WI_SCDP,
  732.                                                                     MUIA_Aboutmui_Application,AP_SCDP,
  733.                                                                     End;
  734.                                                             if(WI_AboutMUI)
  735.                                                                 set(WI_AboutMUI,MUIA_Window_Open,TRUE);
  736.                                                             else
  737.                                                                 DisplayBeep(0);
  738.                                                             break;
  739.                                                         case MEN_MUI:
  740.                                                             DoMethod(AP_SCDP,MUIM_Application_OpenConfigWindow,0);
  741.                                                             break;
  742.                                                         case ID_Volume:
  743.                                                             get(SL_Volume,MUIA_Slider_Level,&a);
  744.                                                             CDSetVolume(a);
  745.                                                             break;
  746.                                                         case ID_Play:
  747.                                                             switch(pstatus)
  748.                                                             {
  749.                                                                 case NORMAL:
  750.                                                                     switch(status)
  751.                                                                     {
  752.                                                                         case STOPPED:
  753.                                                                             track=1;
  754.                                                                             while((TOCflags[track-1]&1) && track<=TOClength)
  755.                                                                                 track++;
  756.                                                                             if(track>TOClength)
  757.                                                                             {
  758.                                                                                 CDStop();
  759.                                                                                 track=0;
  760.                                                                             }
  761.                                                                             else
  762.                                                                             {
  763.                                                                                 CDPlay(TOCaddr[track-1],TOCaddr[TOClength]-TOCaddr[track-1]);
  764.                                                                                 CDGetPos(FALSE);
  765.                                                                             }
  766.                                                                             break;
  767.                                                                         case PAUSED:
  768.                                                                             CDResume();
  769.                                                                             break;
  770.                                                                     }
  771.                                                                     break;
  772.                                                                 case SHUFFLE:
  773.                                                                     switch(status)
  774.                                                                     {
  775.                                                                         case STOPPED:
  776.                                                                             DoShuffle();
  777.                                                                             if(programmed[0])
  778.                                                                             {
  779.                                                                                 a=programmed[0];
  780.                                                                                 pactual=1;
  781.                                                                                 CDPlay(TOCaddr[a-1],TOCaddr[TOClength]-TOCaddr[a-1]);
  782.                                                                                 CDGetPos(FALSE);
  783.                                                                             }
  784.                                                                             break;
  785.                                                                         case PAUSED:
  786.                                                                             CDResume();
  787.                                                                             break;
  788.                                                                     }
  789.                                                                     break;
  790.                                                                 case PROGRAM:
  791.                                                                     switch(status)
  792.                                                                     {
  793.                                                                         case STOPPED:
  794.                                                                             DoProgram();
  795.                                                                             if(programmed[0])
  796.                                                                             {
  797.                                                                                 a=programmed[0];
  798.                                                                                 pactual=1;
  799.                                                                                 CDPlay(TOCaddr[a-1],TOCaddr[TOClength]-TOCaddr[a-1]);
  800.                                                                                 CDGetPos(FALSE);
  801.                                                                             }
  802.                                                                             break;
  803.                                                                         case PAUSED:
  804.                                                                             CDResume();
  805.                                                                             break;
  806.                                                                     }
  807.                                                                     break;
  808.                                                             }
  809.                                                             break;
  810.                                                         case ID_Eject:
  811.                                                             if(trayout)
  812.                                                             {
  813.                                                                 CDLoad();
  814.                                                                 trayout=FALSE;
  815.                                                             }
  816.                                                             else
  817.                                                             {
  818.                                                                 CDEject();
  819.                                                                 trayout=TRUE;
  820.                                                             }
  821.                                                             break;
  822.                                                         case ID_Pause:
  823.                                                             if(status==PAUSED)
  824.                                                                 CDResume();
  825.                                                             else
  826.                                                                 CDPause();
  827.                                                             break;
  828.                                                         case ID_Stop:
  829.                                                             CDStop();
  830.                                                             break;
  831.                                                         case ID_Rewind:
  832.                                                             if(status==PLAYING && actualindex<14400000 && actualindex>750)
  833.                                                             {
  834.                                                                 CDGetPos(FALSE);
  835.                                                                 totalindex-=750;
  836.                                                                 CDPlay(totalindex,TOCaddr[TOClength]-totalindex);
  837.                                                                 CDGetPos(FALSE);
  838.                                                             }
  839.                                                             break;
  840.                                                         case ID_FastForward:
  841.                                                             if(status==PLAYING && totalindex<TOCaddr[track]-750 && actualindex>0)
  842.                                                             {
  843.                                                                 CDGetPos(FALSE);
  844.                                                                 totalindex+=750;
  845.                                                                 CDPlay(totalindex,TOCaddr[TOClength]-totalindex);
  846.                                                                 CDGetPos(FALSE);
  847.                                                             }
  848.                                                             break;
  849.                                                         case ID_Previous:
  850.                                                             if(status==PLAYING)
  851.                                                             {
  852.                                                                 CDGetPos(FALSE);
  853.                                                                 if(totalindex-TOCaddr[track-1]>(75*5))
  854.                                                                 {
  855.                                                                     CDPlay(TOCaddr[track-1],TOCaddr[TOClength]-TOCaddr[track-1]);
  856.                                                                 }
  857.                                                                 else
  858.                                                                 {
  859.                                                                     switch(pstatus)
  860.                                                                     {
  861.                                                                         case NORMAL:
  862.                                                                             if(onevalid)
  863.                                                                             {
  864.                                                                                 track--;
  865.                                                                                 if(!track)
  866.                                                                                     track=TOClength;
  867.                                                                                 while(TOCflags[track-1])
  868.                                                                                 {
  869.                                                                                     track--;
  870.                                                                                     if(!track)
  871.                                                                                         track=TOClength;
  872.                                                                                 }
  873.                                                                                 CDPlay(TOCaddr[track-1],TOCaddr[TOClength]-TOCaddr[track-1]);
  874.                                                                             }
  875.                                                                             break;
  876.                                                                         default:
  877.                                                                             if(onevalid && pactual>1)
  878.                                                                             {
  879.                                                                                 pactual--;
  880.                                                                                 track=programmed[pactual-1];
  881.                                                                                 CDPlay(TOCaddr[track-1],TOCaddr[track]-TOCaddr[track-1]);
  882.                                                                             }
  883.                                                                             break;
  884.                                                                     }
  885.                                                                 }
  886.                                                                 CDGetPos(FALSE);
  887.                                                             }
  888.                                                             break;
  889.                                                         case ID_Next:
  890.                                                             if(status==PLAYING)
  891.                                                             {
  892.                                                                 CDGetPos(FALSE);
  893.                                                                 {
  894.                                                                     switch(pstatus)
  895.                                                                     {
  896.                                                                         case NORMAL:
  897.                                                                             if(onevalid)
  898.                                                                             {
  899.                                                                                 track++;
  900.                                                                                 if(track>TOClength)
  901.                                                                                     track=1;
  902.                                                                                 while(TOCflags[track-1])
  903.                                                                                 {
  904.                                                                                     track++;
  905.                                                                                     if(track>TOClength)
  906.                                                                                         track=1;
  907.                                                                                 }
  908.                                                                                 CDPlay(TOCaddr[track-1],TOCaddr[TOClength]-TOCaddr[track-1]);
  909.                                                                             }
  910.                                                                             break;
  911.                                                                         default:
  912.                                                                             if(onevalid && programmed[pactual])
  913.                                                                             {
  914.                                                                                 pactual++;
  915.                                                                                 track=programmed[pactual-1];
  916.                                                                                 CDPlay(TOCaddr[track-1],TOCaddr[track]-TOCaddr[track-1]);
  917.                                                                             }
  918.                                                                             break;
  919.                                                                     }
  920.                                                                 }
  921.                                                                 CDGetPos(FALSE);
  922.                                                             }
  923.                                                             break;
  924.                                                         case ID_TrackSelect:
  925.                                                             get(LV_TrackSelect,MUIA_List_Active,&a);
  926.                                                             if(a>=0 && a<TOClength && !TOCflags[a])
  927.                                                             {
  928.                                                                 pstatus=NORMAL;
  929.                                                                 set(BT_ProgramL,MUIA_Selected,FALSE);
  930.                                                                 set(BT_Shuffle,MUIA_Selected,FALSE);
  931.                                                                 track=a+1;
  932.                                                                 CDPlay(TOCaddr[track-1],TOCaddr[TOClength]-TOCaddr[track-1]);
  933.                                                                 CDGetPos(FALSE);
  934.                                                             }
  935.                                                             break;
  936.                                                         case ID_ProgramL:
  937.                                                             get(BT_ProgramL,MUIA_Selected,&a);
  938.                                                             if(a)
  939.                                                             {
  940.                                                                 pstatus=PROGRAM;
  941.                                                                 DoProgram();
  942.                                                                 if(status==PLAYING && programmed[0])
  943.                                                                 {
  944.                                                                     a=programmed[0];
  945.  
  946.                                                                     CDPlay(TOCaddr[a-1],TOCaddr[TOClength]-TOCaddr[a-1]);
  947.                                                                     pactual=1;
  948.                                                                 }
  949.                                                                 else if(status!=STOPPED)
  950.                                                                     CDStop();
  951.                                                             }
  952.                                                             else
  953.                                                                 if(pstatus==PROGRAM)
  954.                                                                     pstatus=NORMAL;
  955.                                                             break;
  956.                                                         case ID_Shuffle:
  957.                                                             get(BT_Shuffle,MUIA_Selected,&a);
  958.                                                             if(a)
  959.                                                             {
  960.                                                                 pstatus=SHUFFLE;
  961.                                                                 DoShuffle();
  962.                                                                 if(status==PLAYING && programmed[0])
  963.                                                                 {
  964.                                                                     a=programmed[0];
  965.  
  966.                                                                     CDPlay(TOCaddr[a-1],TOCaddr[a]-TOCaddr[a-1]);
  967.                                                                     pactual=1;
  968.                                                                 }
  969.                                                                 else if(status!=STOPPED)
  970.                                                                     CDStop();
  971.                                                             }
  972.                                                             else
  973.                                                                 if(pstatus==SHUFFLE)
  974.                                                                     pstatus=NORMAL;
  975.                                                             break;
  976.                                                         case ID_List:
  977.                                                             FillList();
  978.                                                             break;
  979.                                                         case ID_ChangeActive:
  980.                                                             DoMethod(LV_TitleList,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&strptr);
  981.                                                             if(strptr)
  982.                                                             {
  983.                                                                 strcpy(buff,strptr);
  984.                                                                 set(ST_Title,MUIA_String_Contents,buff+4);
  985.                                                             }
  986.                                                             break;
  987.                                                         case ID_Confirm:
  988.                                                             get(ST_Title,MUIA_String_Contents,&strptr);
  989.                                                             get(LV_TitleList,MUIA_List_Active,&a);
  990.                                                             if(a>=0 && a<TOClength)
  991.                                                             {
  992.                                                                 sprintf(buff,"%02d: %s",a+1,strptr);
  993.                                                                 set(LV_TitleList,MUIA_List_Quiet,TRUE);
  994.                                                                 DoMethod(LV_TitleList,MUIM_List_Remove,a);
  995.                                                                 DoMethod(LV_TitleList,MUIM_List_InsertSingle,buff,a);
  996.                                                                 set(LV_TitleList,MUIA_List_Quiet,FALSE);
  997.                                                             }
  998.                                                             break;
  999.                                                         case ID_Save:
  1000.                                                             {
  1001.                                                                 FILE *f;
  1002.                                                                 char *s1, *s2;
  1003.                                                                 sprintf(buff,"PROGDIR:Disks/%s",TOCCDID);
  1004.                                                                 if(f=fopen(buff,"w"))
  1005.                                                                 {
  1006.                                                                     get(ST_Artist,MUIA_String_Contents,&s1);
  1007.                                                                     get(ST_CDTitle,MUIA_String_Contents,&s2);
  1008.                                                                     fprintf(f,"%s\n%s\n",s1,s2);
  1009.                                                                     for(a=0;a<TOClength;a++)
  1010.                                                                     {
  1011.                                                                         DoMethod(LV_TitleList,MUIM_List_GetEntry,a,&strptr);
  1012.                                                                         fprintf(f,"%s\n",((char *)strptr)+4);
  1013.                                                                     }
  1014.                                                                     fclose(f);
  1015.                                                                 }
  1016.                                                             }
  1017.                                                         case ID_Use:
  1018.                                                             get(ST_Artist,MUIA_String_Contents,&strptr);
  1019.                                                             strcpy(TOCCDartist,strptr);
  1020.                                                             get(ST_CDTitle,MUIA_String_Contents,&strptr);
  1021.                                                             strcpy(TOCCDtitle,strptr);
  1022.                                                             set(LV_TrackSelect,MUIA_List_Quiet,TRUE);
  1023.                                                             DoMethod(LV_TrackSelect,MUIM_List_Clear);
  1024.                                                             for(a=0;a<TOClength;a++)
  1025.                                                             {
  1026.                                                                 DoMethod(LV_TitleList,MUIM_List_GetEntry,a,&strptr);
  1027.                                                                 DoMethod(LV_TrackSelect,MUIM_List_InsertSingle,strptr,MUIV_List_Insert_Bottom);
  1028.                                                             }
  1029.                                                             set(LV_TrackSelect,MUIA_List_Quiet,FALSE);
  1030.                                                             refresh=TRUE;
  1031.                                                             set(WI_List,MUIA_Window_Open,FALSE);
  1032.                                                             CDGetPos(FALSE);
  1033.                                                             break;
  1034.                                                         case ID_PInsert:
  1035.                                                             DoMethod(LV_PList,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&strptr);
  1036.                                                             if(strptr)
  1037.                                                             {
  1038.                                                                 DoMethod(LV_Program,MUIM_List_InsertSingle,strptr,MUIV_List_Insert_Bottom);
  1039.                                                             }
  1040.                                                             break;
  1041.                                                         case ID_ProgramR:
  1042.                                                             set(LV_Program,MUIA_List_Quiet,TRUE);
  1043.                                                             DoMethod(LV_Program,MUIM_List_Clear);
  1044.                                                             a=0;
  1045.                                                             while(pprog[a])
  1046.                                                             {
  1047.                                                                 DoMethod(LV_TrackSelect,MUIM_List_GetEntry,pprog[a]-1,&strptr);
  1048.                                                                 DoMethod(LV_Program,MUIM_List_InsertSingle,strptr,MUIV_List_Insert_Bottom);
  1049.                                                                 a++;
  1050.                                                             }
  1051.                                                             set(LV_Program,MUIA_List_Quiet,FALSE);
  1052.                                                             set(WI_Program,MUIA_Window_ActiveObject,LV_PList);
  1053.                                                             set(WI_Program,MUIA_Window_Open,TRUE);
  1054.                                                             break;
  1055.                                                         case ID_PUse:
  1056.                                                             a=0;
  1057.                                                             do
  1058.                                                             {
  1059.                                                                 DoMethod(LV_Program,MUIM_List_GetEntry,a,&strptr);
  1060.                                                                 if(strptr)
  1061.                                                                 {
  1062.                                                                     pprog[a]=(strptr[0]-'0')*10+strptr[1]-'0';
  1063.                                                                     a++;
  1064.                                                                 }
  1065.                                                             }while(strptr);
  1066.                                                             pprog[a]=0;
  1067.                                                             set(WI_Program,MUIA_Window_Open,FALSE);
  1068.                                                             break;
  1069.                                                         case ID_PSave:
  1070.                                                             a=0;
  1071.                                                             do
  1072.                                                             {
  1073.                                                                 DoMethod(LV_Program,MUIM_List_GetEntry,a,&strptr);
  1074.                                                                 if(strptr)
  1075.                                                                 {
  1076.                                                                     pprog[a]=(strptr[0]-'0')*10+strptr[1]-'0';
  1077.                                                                     a++;
  1078.                                                                 }
  1079.                                                             }while(strptr);
  1080.                                                             pprog[a]=0;
  1081.                                                             sprintf(buff,"PROGDIR:disks/%s",TOCCDID);
  1082.                                                             buff[14]='P';
  1083.                                                             buff[15]='R';
  1084.                                                             if(f=fopen(buff,"w"))
  1085.                                                             {
  1086.                                                                 a=0;
  1087.  
  1088.                                                                 while(pprog[a])
  1089.                                                                     putc(pprog[a++],f);
  1090.  
  1091.                                                                 fclose(f);
  1092.                                                             }
  1093.                                                             set(WI_Program,MUIA_Window_Open,FALSE);
  1094.                                                             break;
  1095.                                                         default:
  1096.                                                             break;
  1097.                                                     }
  1098.                                                     if(vamos)
  1099.                                                     {
  1100.                                                         CDGetPos(TRUE);
  1101.                                                         vamos=FALSE;
  1102.                                                     }
  1103.  
  1104.                                                     if(i && signals) signals=Wait(signals|(1<<tmsgport->mp_SigBit));
  1105.                                                 }
  1106.  
  1107.                                                 Wait(1<<tmsgport->mp_SigBit);
  1108.                                                 GetMsg(tmsgport);
  1109.                                             }
  1110.                                             else
  1111.                                             {
  1112.                                                 if(CL_ProgramList)
  1113.                                                     MUI_DeleteCustomClass(CL_ProgramList);
  1114.                                                 errorstr=glstr(MSG_FailApplication);
  1115.                                             }
  1116.  
  1117.                                             FreeMem(TOCbuf,MAX_TOC_LEN);
  1118.                                         }
  1119.                                         else
  1120.                                             errorstr=glstr(MSG_FailMemory);
  1121.  
  1122.                                         FreeMem(scsidata,MAX_DATA_LEN);
  1123.                                     }
  1124.                                     else
  1125.                                         errorstr=glstr(MSG_FailMemory);
  1126.  
  1127.                                     CloseDevice((struct IORequest *)tioreq);
  1128.                                 }
  1129.                                 else
  1130.                                     errorstr=glstr(MSG_FailNoTimer);
  1131.  
  1132.                                 DeleteIORequest(tioreq);
  1133.                             }
  1134.                             else
  1135.                                 errorstr=glstr(MSG_FailNoIO);
  1136.  
  1137.                             DeleteMsgPort(tmsgport);
  1138.                         }
  1139.                         else
  1140.                             errorstr=glstr(MSG_FailNoMP);
  1141.  
  1142.                         FreeMem(scsisense,SENSE_LEN);
  1143.                     }
  1144.                     else
  1145.                         errorstr=glstr(MSG_FailMemory);
  1146.  
  1147.                     FreeMem(scsicmd,sizeof(SCSICMD));
  1148.                 }
  1149.                 else
  1150.                     errorstr=glstr(MSG_FailMemory);
  1151.  
  1152.                 CloseDevice((struct IORequest *)ioreq);
  1153.             }
  1154.             else
  1155.                 errorstr=glstr(MSG_FailNoDevice);
  1156.  
  1157.             DeleteIORequest(ioreq);
  1158.         }
  1159.         else
  1160.             errorstr=glstr(MSG_FailNoIO);
  1161.  
  1162.         DeleteMsgPort(msgport);
  1163.     }
  1164.     else
  1165.         errorstr=glstr(MSG_FailNoMP);
  1166.  
  1167.     if(mydo)
  1168.         FreeDiskObject(mydo);
  1169.  
  1170.     fail(AP_SCDP,errorstr);
  1171.  
  1172.     return 0;
  1173. }
  1174.  
  1175. int DoScsiCmd(UBYTE *data, int datasize, UBYTE *cmd, int cmdsize, UBYTE flags)
  1176. {
  1177.     ioreq->io_Length=sizeof(SCSICMD);
  1178.     ioreq->io_Data=scsicmd;
  1179.     ioreq->io_Command=HD_SCSICMD;
  1180.  
  1181.     scsicmd->scsi_Data=(APTR)data;
  1182.     scsicmd->scsi_Length=datasize;
  1183.     scsicmd->scsi_SenseActual=0;
  1184.     scsicmd->scsi_SenseData=scsisense;
  1185.     scsicmd->scsi_Command=cmd;
  1186.     scsicmd->scsi_CmdLength=cmdsize;
  1187.     scsicmd->scsi_Flags=flags;
  1188.  
  1189.     DoIO((struct IORequest *) ioreq);
  1190.  
  1191.     return ioreq->io_Error;
  1192. }
  1193.  
  1194. void CDEject(void)
  1195. {
  1196.     static SCSICMD6 command=
  1197.     {
  1198.         SCSI_CMD_SSU,
  1199.         0,
  1200.         PAD,
  1201.         PAD,
  1202.         0,
  1203.         PAD,
  1204.     };
  1205.  
  1206.     int err;
  1207.  
  1208.     command.b4=2;   /* I think this number is important: (0=STOP, 1=?, 2=EJECT, 3=LOAD, 4=STOP?)*/
  1209.  
  1210.     if(err=DoScsiCmd(0,0,(UBYTE *)&command,sizeof(command),SCSIF_READ|SCSIF_AUTOSENSE))
  1211.         return;
  1212. }
  1213.  
  1214. void CDLoad(void)
  1215. {
  1216.     static SCSICMD6 command=
  1217.     {
  1218.         SCSI_CMD_SSU,
  1219.         0,
  1220.         PAD,
  1221.         PAD,
  1222.         0,
  1223.         PAD,
  1224.     };
  1225.  
  1226.     int err;
  1227.  
  1228.     command.b4=3;   /* I think this number is important: (0=STOP, 1=?, 2=EJECT, 3=LOAD, 4=STOP?)*/
  1229.  
  1230.     if(err=DoScsiCmd(0,0,(UBYTE *)&command,sizeof(command),SCSIF_READ|SCSIF_AUTOSENSE))
  1231.         return;
  1232. }
  1233.  
  1234. void CDStop(void)
  1235. {
  1236.     static SCSICMD6 command=
  1237.     {
  1238.         SCSI_CMD_SSU,
  1239.         0,
  1240.         PAD,
  1241.         PAD,
  1242.         0,
  1243.         PAD,
  1244.     };
  1245.  
  1246.     int err;
  1247.  
  1248.     command.b4=0;   /* I think this number is important: (0=STOP, 1=?, 2=EJECT, 3=LOAD, 4=STOP?)*/
  1249.  
  1250.     if(status==PLAYING || status==PAUSED)
  1251.         status=STOPPED;
  1252.  
  1253.     userstop=TRUE;
  1254.  
  1255.     if(err=DoScsiCmd(0,0,(UBYTE *)&command,sizeof(command),SCSIF_READ|SCSIF_AUTOSENSE))
  1256.         return;
  1257. }
  1258.  
  1259. void CDGetPos(BOOL settimer)
  1260. {
  1261.     APTR *strptr;
  1262.     char buff[256];
  1263.     BOOL redraw=FALSE;
  1264.  
  1265.     static SCSICMD10 command=
  1266.     {
  1267.         SCSI_CMD_READSUBCHANNEL,
  1268.         0,
  1269.         0x40,
  1270.         0,
  1271.         PAD,
  1272.         PAD,
  1273.         0,
  1274.         0,0,
  1275.         PAD
  1276.     };
  1277.  
  1278.     int err;
  1279.     ULONG microsleft;
  1280.  
  1281.     command.b2=0x40;
  1282.     command.b3=1;
  1283.     command.b6=0;
  1284.     command.b7=255;
  1285.     command.b8=255;
  1286.  
  1287.     if(err=DoScsiCmd((UBYTE *)scsidata, MAX_DATA_LEN, (UBYTE *) &command, sizeof(command),SCSIF_READ|SCSIF_AUTOSENSE))
  1288.     {
  1289.         track=0;
  1290.         status=NODISK;
  1291.         actualindex=totalindex=0;
  1292.         pstatus=NORMAL;
  1293.         if(validTOC)
  1294.         {
  1295.             set(WI_List,MUIA_Window_Open,FALSE);
  1296.             set(WI_Program,MUIA_Window_Open,FALSE);
  1297.             set(BT_List,MUIA_Disabled,TRUE);
  1298.             set(BT_ProgramR,MUIA_Disabled,TRUE);
  1299.             set(BT_ProgramL,MUIA_Selected,FALSE);
  1300.             set(BT_Shuffle,MUIA_Selected,FALSE);
  1301.             set(BT_Repeat,MUIA_Selected,FALSE);
  1302.             set(TX_Track,MUIA_Text_Contents,"--");
  1303.             set(TX_TitleTime,MUIA_Text_Contents,"--:--/--:--");
  1304.             set(TX_CDTime,MUIA_Text_Contents,"--:--/--:--");
  1305.             set(TX_Artist,MUIA_Text_Contents,glstr(MSG_NoDisc));
  1306.             set(TX_Title,MUIA_Text_Contents,"");
  1307.             DoMethod(LV_TrackSelect,MUIM_List_Clear);
  1308.             DoMethod(LV_PList,MUIM_List_Clear);
  1309.             DoMethod(LV_Program,MUIM_List_Clear);
  1310.             pprog[0]=0;
  1311.             validTOC=0;
  1312.             microsleft=1000000;
  1313.         }
  1314.     }
  1315.     else
  1316.     {
  1317.         if(!validTOC)
  1318.         {
  1319.             CDReadContents();
  1320.         }
  1321.  
  1322.         /* Now one looks at scsidata[1]. It may be:
  1323.             0x11:   Playing.
  1324.             0x12:   Pause.
  1325.             other:  Stopped.
  1326.  
  1327.            scsidata[6] has the number of the track being played.
  1328.  
  1329.            scsidata[12..15] contains the address which is being played (75ths of second from track start).
  1330.            scsidata[8..11] contains the address from the begin of the CD.
  1331.         */
  1332.         switch(scsidata[1])
  1333.         {
  1334.             case 0x11:
  1335.                 if(status!=PLAYING)
  1336.                 {
  1337.                     status=PLAYING;
  1338.                     redraw=TRUE;
  1339.                 }
  1340.                 if(track!=scsidata[6])
  1341.                 {
  1342.                     track=scsidata[6];
  1343.                     redraw=TRUE;
  1344.                 }
  1345.                 trayout=FALSE;
  1346.                 actualindex=(scsidata[12] << 24) | (scsidata[13] << 16) | (scsidata[14] << 8) | (scsidata[15]);
  1347.                 totalindex=(scsidata[8] << 24) | (scsidata[9] << 16) | (scsidata[10] << 8) | (scsidata[11]);
  1348.                 microsleft=(75-(actualindex%75))*13333+25;
  1349.                 if(TOCaddr[track]-totalindex<80)
  1350.                 {
  1351.                     microsleft=(TOCaddr[track]-totalindex)*13333;
  1352.                     if(TOCaddr[TOClength]-totalindex<80 && !skip)
  1353.                         actuate=1;
  1354.                 }
  1355.                 if(pstatus!=NORMAL && track>programmed[pactual-1])
  1356.                 {
  1357.                     if(!skip)
  1358.                         actuate=2;
  1359.                     microsleft=1;
  1360.                 }
  1361.                 break;
  1362.             case 0x12:
  1363.                 status=PAUSED;
  1364.                 redraw=TRUE;
  1365.                 track=scsidata[6];
  1366.                 trayout=FALSE;
  1367.                 actualindex=(scsidata[12] << 24) | (scsidata[13] << 16) | (scsidata[14] << 8) | (scsidata[15]);
  1368.                 totalindex=(scsidata[8] << 24) | (scsidata[9] << 16) | (scsidata[10] << 8) | (scsidata[11]);
  1369.                 microsleft=1000000;
  1370.                 break;
  1371.             default:
  1372.                 status=STOPPED;
  1373.                 redraw=TRUE;
  1374.                 trayout=FALSE;
  1375.                 actualindex=totalindex=0;
  1376.                 track=0;
  1377.                 microsleft=1000000;
  1378.                 if(!userstop && !skip)
  1379.                     actuate=3;
  1380.                 break;
  1381.         }
  1382.  
  1383.         if(refresh)
  1384.         {
  1385.             redraw=TRUE;
  1386.             refresh=FALSE;
  1387.         }
  1388.  
  1389.         if(totalindex>=TOCaddr[TOClength])
  1390.         {
  1391.             if(!skip)
  1392.                 actuate=1;
  1393.             track=actualindex=totalindex=0;
  1394.         }
  1395.  
  1396.         if(track>0 && track<=TOClength)
  1397.         {
  1398.             if(pstatus==NORMAL || track==programmed[pactual-1])
  1399.                 set(LV_TrackSelect,MUIA_List_Active,track-1);
  1400.             sprintf(buff,"%02d",track);
  1401.             set(TX_Track,MUIA_Text_Contents,buff);
  1402.             sprintf(buff,"%02.2d:%02.2d/%02.2d:%02.2d",min(actualindex/(60*75),99),(actualindex/75)%60,(TOCaddr[track]-TOCaddr[track-1])/(60*75),((TOCaddr[track]-TOCaddr[track-1])/75)%60 );
  1403.             set(TX_TitleTime,MUIA_Text_Contents,buff);
  1404.             sprintf(buff,"%02.2d:%02.2d/%02.2d:%02.2d",totalindex/(60*75),(totalindex/75)%60,(TOCaddr[TOClength])/(60*75),((TOCaddr[TOClength])/75)%60 );
  1405.             set(TX_CDTime,MUIA_Text_Contents,buff);
  1406.             if(redraw)
  1407.             {
  1408.                 set(TX_Artist,MUIA_Text_Contents,TOCCDartist);
  1409.                 DoMethod(LV_TrackSelect,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&strptr);
  1410.                 if(pstatus==NORMAL || track==programmed[pactual-1])
  1411.                     set(TX_Title,MUIA_Text_Contents,((char *)strptr)+4);
  1412.             }
  1413.         }
  1414.         else
  1415.         {
  1416.             if(redraw)
  1417.             {
  1418.                 set(LV_TrackSelect,MUIA_List_Active,MUIV_List_Active_Off);
  1419.                 sprintf(buff,"--:--/%02.2d:%02.2d",(TOCaddr[TOClength])/(60*75),((TOCaddr[TOClength])/75)%60 );
  1420.                 set(TX_CDTime,MUIA_Text_Contents,buff);
  1421.                 set(TX_Track,MUIA_Text_Contents,"--");
  1422.                 set(TX_TitleTime,MUIA_Text_Contents,"--:--/--:--");
  1423.                 set(TX_Artist,MUIA_Text_Contents,TOCCDartist);
  1424.                 set(TX_Title,MUIA_Text_Contents,TOCCDtitle);
  1425.             }
  1426.         }
  1427.     }
  1428.     if(settimer)
  1429.     {
  1430.         if(skip)
  1431.             skip--;
  1432.         tioreq->tr_node.io_Command=TR_ADDREQUEST;
  1433.         tioreq->tr_time.tv_secs=microsleft/1000000;
  1434.         tioreq->tr_time.tv_micro=microsleft%1000000;
  1435.         SendIO((struct IORequest *)tioreq);
  1436.     }
  1437. }
  1438.  
  1439.  
  1440. /* THIS FUNCTION IS **NOT** SAFE!!!
  1441. ** I know it somehow works on my system, but I don't know how.
  1442. ** Anyway I leave it here, because I have nothing better. Perhaps I'll
  1443. ** find something better some day.        I DON'T KNOW HOW IT WORKS!!!
  1444. ** It takes a volume between 1 and 31.
  1445. */
  1446. void CDSetVolume(int volume)
  1447. {
  1448.     static SCSICMD6 modecommand;
  1449.     static struct volmodedata
  1450.     {
  1451.         UBYTE head[4];
  1452.         UBYTE page;     /* page code 0x0e */
  1453.         UBYTE plength;  /* page length */
  1454.         UBYTE b2;       /* bit2: Immed, bit 1: SOTC */
  1455.         UBYTE b3;       /* reserved */
  1456.         UBYTE b4;       /* reserved */
  1457.         UBYTE b5;       /* bit 7: APRVal, bit 3-0: format of LBAs / Sec. */
  1458.         UWORD bps;      /* logical blocks per second audio playback */
  1459.         UBYTE out0;     /* lower 4 bits: output port 0 channel selection */
  1460.         UBYTE vol0;     /* output port 0 volume */
  1461.         UBYTE out1;     /* lower 4 bits: output port 1 channel selection */
  1462.         UBYTE vol1;     /* output port 1 volume */
  1463.         UBYTE out2;     /* lower 4 bits: output port 2 channel selection */
  1464.         UBYTE vol2;     /* output port 2 volume */
  1465.         UBYTE out3;     /* lower 4 bits: output port 3 channel selection */
  1466.         UBYTE vol3;     /* output port 3 volume */
  1467.     } modedata;
  1468.     int i,err,j;
  1469.  
  1470.     if(!volumecontrol)
  1471.         return;
  1472.  
  1473.     for(i=0;i<4;i++)
  1474.         modedata.head[i]=0;
  1475.  
  1476.     modecommand.opcode=SCSI_CMD_MSE;
  1477.     modecommand.b1=0;            /* 0 */
  1478.     modecommand.b2=0x0e;         /* 0x0e */
  1479.     modecommand.b3=0;            /* 0 */
  1480.     modecommand.b4=64; /* MAX_DATA_LEN; */
  1481.     modecommand.control=0;
  1482.  
  1483.     if(err=DoScsiCmd((UBYTE *) scsidata, MAX_DATA_LEN, (UBYTE *) &modecommand, sizeof(modecommand), SCSIF_READ|SCSIF_AUTOSENSE))
  1484.         return;
  1485.  
  1486. /*    for(i=0;i<64;i++)
  1487.         printf("%02x",(int)scsidata[i]);
  1488.         printf("\n"); */
  1489.  
  1490.     for (j = (scsidata[0]+1), i = scsidata[3] + 4; i < j; i += scsidata[i+1] + 2)
  1491.         memcpy (&modedata.page, &scsidata[i], 16);
  1492.  
  1493.     modedata.page = 0x0e;
  1494.     modedata.plength = 0x0e;
  1495. /*    modedata.b2=4; */
  1496. /*    modedata.b5=0; */
  1497. /*    modedata.bps=NUM_OF_CDDAFRAMES; (0 en PlayCD)*/
  1498. /*    modedata.out0=1; */
  1499. /*    modedata.out1=2; */
  1500. /*    modedata.out2=0; */
  1501. /*    modedata.out3=0; */
  1502.  
  1503.     if(volume==-1)
  1504.     {
  1505.         volume=(modedata.vol0+modedata.vol1-2)/16;
  1506.         volume=max(1,min(31,volume));
  1507.         set(SL_Volume,MUIA_Slider_Level,volume);
  1508.     }
  1509.  
  1510.     modedata.vol0 = volume*8+1;
  1511.     modedata.vol1 = volume*8+1;
  1512.     modedata.vol2 = volume*8+1;
  1513.     modedata.vol3 = volume*8+1;
  1514.  
  1515.     modecommand.opcode      = SCSI_CMD_MSL;
  1516.     modecommand.b1          = 0x10;                /* 0 antes 0x10 */
  1517.     modecommand.b2          = 0;                   /* 0 */
  1518.     modecommand.b3          = 0;    /* 0x14 */
  1519.     modecommand.b4          = sizeof (modedata);   /* 0 */
  1520.     modecommand.control     = 0;
  1521.  
  1522.     if ((err = DoScsiCmd ((UBYTE *) &modedata, sizeof(modedata),
  1523.                           (UBYTE *) &modecommand, sizeof (modecommand),
  1524.                           (SCSIF_WRITE | SCSIF_AUTOSENSE))) != 0)
  1525.         return;
  1526.  
  1527. }
  1528.  
  1529. void CDPause(void)
  1530. {
  1531.     static SCSICMD10 command =
  1532.     {
  1533.         SCSI_CMD_PAUSERESUME,
  1534.         PAD,
  1535.         0,
  1536.         0,
  1537.         0,
  1538.         0,
  1539.         0,
  1540.         0,
  1541.         0,
  1542.         PAD,
  1543.     };
  1544.  
  1545.     command.b8 = 0x00; /* 0x01 for resuming */
  1546.  
  1547.     DoScsiCmd (NULL, NULL,
  1548.                (UBYTE *) & command, sizeof (command),
  1549.                (SCSIF_READ | SCSIF_AUTOSENSE));
  1550.     if(status==PLAYING)
  1551.         status=PAUSED;
  1552. }
  1553.  
  1554. void CDResume(void)
  1555. {
  1556.     static SCSICMD10 command =
  1557.     {
  1558.         SCSI_CMD_PAUSERESUME,
  1559.         PAD,
  1560.         0,
  1561.         0,
  1562.         0,
  1563.         0,
  1564.         0,
  1565.         0,
  1566.         0,
  1567.         PAD,
  1568.     };
  1569.  
  1570.     command.b8 = 0x01; /* 0x00 for pausing */
  1571.  
  1572.     DoScsiCmd (NULL, NULL,
  1573.                (UBYTE *) & command, sizeof (command),
  1574.                (SCSIF_READ | SCSIF_AUTOSENSE));
  1575. }
  1576.  
  1577. void CDPlay(int start, int length)
  1578. {
  1579.     static SCSICMD12 command =
  1580.     {
  1581.         SCSI_CMD_PLAYAUDIO12,
  1582.         PAD,
  1583.         0, 0, 0, 0,
  1584.         0, 0, 0, 0,
  1585.         PAD,
  1586.         PAD,
  1587.     };
  1588.     command.b2=(start&0xff000000)>>24;
  1589.     command.b3=(start&0x00ff0000)>>16;
  1590.     command.b4=(start&0x0000ff00)>>8;
  1591.     command.b5=(start&0x000000ff);
  1592.  
  1593.     command.b6=(length&0xff000000)>>24;
  1594.     command.b7=(length&0x00ff0000)>>16;
  1595.     command.b8=(length&0x0000ff00)>>8;
  1596.     command.b9=(length&0x000000ff);
  1597.  
  1598.     skip=5;
  1599.  
  1600.     userstop=FALSE;
  1601.     refresh=TRUE;
  1602.  
  1603.     DoScsiCmd((UBYTE *)scsidata,MAX_DATA_LEN,(UBYTE *)&command,sizeof(command),SCSIF_READ|SCSIF_AUTOSENSE);
  1604. }
  1605.  
  1606. void CDReadContents(void)
  1607. {
  1608.     char buff[1024],buff2[256];
  1609.     FILE *f;
  1610.     static SCSICMD10 command=
  1611.     {
  1612.         SCSI_CMD_READTOC,
  1613.         0,
  1614.         PAD,PAD,PAD,PAD,
  1615.         0,
  1616.         0x03,0x24,
  1617.         PAD
  1618.     };
  1619.     int err,TOCsize;
  1620.     UBYTE * TOCptr;
  1621.  
  1622.     validTOC=0;
  1623.  
  1624.     if(err=DoScsiCmd((UBYTE *)TOCbuf,MAX_TOC_LEN,(UBYTE *)&command,sizeof(command),SCSIF_READ|SCSIF_AUTOSENSE))
  1625.         return;
  1626.  
  1627.     TOCsize=(TOCbuf[0]<<8)|TOCbuf[1];
  1628.  
  1629.     TOCaddr[2]=TOCaddr[1]=TOCaddr[0]=0;
  1630.     TOClength=0;
  1631.  
  1632.     if(TOCsize>=2);
  1633.         TOCsize-=2;
  1634.  
  1635.     onevalid=FALSE;
  1636.     for(TOCptr=&TOCbuf[4];TOCptr<(&TOCbuf[4]+TOCsize) && TOClength<100;TOCptr+=8)
  1637.     {
  1638.         TOCaddr[TOClength]=(TOCptr[4]<<24)|(TOCptr[5]<<16)|(TOCptr[6]<<8)|(TOCptr[7]);
  1639.         onevalid|=!((TOCflags[TOClength]=(TOCptr[1]&0x04)>>2)&1);
  1640.         TOClength++;
  1641.     }
  1642.     TOClength--;
  1643.  
  1644.     sprintf(TOCCDID,"ID%02d%06X%06X",TOClength,TOCaddr[2],TOCaddr[TOClength]);
  1645.  
  1646.     sprintf(buff,"PROGDIR:disks/%s",TOCCDID);
  1647.     if(f=fopen(buff,"r"))
  1648.     {
  1649.         set(LV_TrackSelect,MUIA_List_Quiet,TRUE);
  1650.         set(LV_PList,MUIA_List_Quiet,TRUE);
  1651.         DoMethod(LV_TrackSelect,MUIM_List_Clear);
  1652.         DoMethod(LV_PList,MUIM_List_Clear);
  1653.         fgets(TOCCDartist,128,f);
  1654.         if(TOCCDartist[strlen(TOCCDartist)-1]=='\n')
  1655.             TOCCDartist[strlen(TOCCDartist)-1]='\0';
  1656.         fgets(TOCCDtitle,128,f);
  1657.         if(TOCCDtitle[strlen(TOCCDtitle)-1]=='\n')
  1658.             TOCCDtitle[strlen(TOCCDtitle)-1]='\0';
  1659.         for(err=0;err<TOClength;err++)
  1660.         {
  1661.             fgets(buff,128,f);
  1662.             if(buff[strlen(buff)-1]=='\n')
  1663.                 buff[strlen(buff)-1]='\0';
  1664.             sprintf(buff2,"%02d: %s",err+1,buff);
  1665.             DoMethod(LV_TrackSelect,MUIM_List_InsertSingle,buff2,MUIV_List_Insert_Bottom);
  1666.             DoMethod(LV_PList,MUIM_List_InsertSingle,buff2,MUIV_List_Insert_Bottom);
  1667.         }
  1668.  
  1669.         fclose(f);
  1670.         set(LV_TrackSelect,MUIA_List_Quiet,FALSE);
  1671.         set(LV_PList,MUIA_List_Quiet,FALSE);
  1672.     }
  1673.     else
  1674.     {
  1675.         set(LV_TrackSelect,MUIA_List_Quiet,TRUE);
  1676.         set(LV_PList,MUIA_List_Quiet,TRUE);
  1677.         DoMethod(LV_TrackSelect,MUIM_List_Clear);
  1678.         DoMethod(LV_PList,MUIM_List_Clear);
  1679.         strcpy(TOCCDartist,glstr(MSG_UnknownArtist));
  1680.         strcpy(TOCCDtitle,glstr(MSG_UnknownTitle));
  1681.         for(err=0;err<TOClength;err++)
  1682.         {
  1683.             if(TOCflags[err]&1)
  1684.                 sprintf(buff2,glstr(MSG_DataTrack),err+1);
  1685.             else
  1686.                 sprintf(buff2,glstr(MSG_TrackNo),err+1,err+1);
  1687.             DoMethod(LV_TrackSelect,MUIM_List_InsertSingle,buff2,MUIV_List_Insert_Bottom);
  1688.             if(!TOCflags[err])
  1689.                 DoMethod(LV_PList,MUIM_List_InsertSingle,buff2,MUIV_List_Insert_Bottom);
  1690.         }
  1691.         set(LV_TrackSelect,MUIA_List_Quiet,FALSE);
  1692.         set(LV_PList,MUIA_List_Quiet,FALSE);
  1693.     }
  1694.     sprintf(buff,"PROGDIR:disks/%s",TOCCDID);
  1695.     buff[14]='P';
  1696.     buff[15]='R';
  1697.     if(f=fopen(buff,"r"))
  1698.     {
  1699.         int ppp,err;
  1700.  
  1701.         err=0;
  1702.  
  1703.         while((ppp=getc(f))!=EOF)
  1704.             pprog[err++]=(ppp>0 && ppp<=TOClength)?ppp:0;
  1705.  
  1706.         pprog[err]=0;
  1707.  
  1708.         fclose(f);
  1709.     }
  1710.     else
  1711.     {
  1712.         pprog[0]=0;
  1713.     }
  1714.     set(BT_List,MUIA_Disabled,FALSE);
  1715.     set(BT_ProgramR,MUIA_Disabled,FALSE);
  1716.     validTOC=1;
  1717. }
  1718.  
  1719. void DoShuffle(void)
  1720. {
  1721.     int i,j,mx=0,k;
  1722.  
  1723.     programmed[0]=0;
  1724.  
  1725.     if(!onevalid)
  1726.         return;
  1727.  
  1728.     srand(time(NULL));
  1729.  
  1730.     for(i=0;i<TOClength;i++)
  1731.         mx+=!TOCflags[i];
  1732.  
  1733.     for(i=0;i<mx;i++)
  1734.     {
  1735.         programmed[i]=rand()%TOClength;
  1736.         k=TRUE;
  1737.         while(k)
  1738.         {
  1739.             k=TOCflags[programmed[i]];
  1740.  
  1741.             for(j=0;j<i;j++)
  1742.                 k|=(programmed[j]==programmed[i]);
  1743.  
  1744.             if(k)
  1745.             {
  1746.                 programmed[i]++;
  1747.                 programmed[i]%=TOClength;
  1748.             }
  1749.         }
  1750.     }
  1751.     for(i=0;i<mx;i++)
  1752.         programmed[i]++;
  1753.     programmed[mx]=0;
  1754. }
  1755.  
  1756. void DoProgram(void)
  1757. {
  1758.     int i;
  1759.     i=0;
  1760.     while(programmed[i]=pprog[i])
  1761.         i++;
  1762. }
  1763.  
  1764. void FillList(void)
  1765. {
  1766.     int i;
  1767.     UBYTE *strptr;
  1768.  
  1769.     set(ST_Artist,MUIA_String_Contents,TOCCDartist);
  1770.     set(ST_CDTitle,MUIA_String_Contents,TOCCDtitle);
  1771.     set(LV_TitleList,MUIA_List_Quiet,TRUE);
  1772.     DoMethod(LV_TitleList,MUIM_List_Clear);
  1773.     for(i=0;i<TOClength;i++)
  1774.     {
  1775.         DoMethod(LV_TrackSelect,MUIM_List_GetEntry,i,&strptr);
  1776.         DoMethod(LV_TitleList,MUIM_List_InsertSingle,strptr,MUIV_List_Insert_Bottom);
  1777.     }
  1778.     set(LV_TitleList,MUIA_List_Active,0);
  1779.     set(LV_TitleList,MUIA_List_Quiet,FALSE);
  1780.     set(WI_List,MUIA_Window_Open,TRUE);
  1781.     set(WI_List,MUIA_Window_ActiveObject,ST_Artist);
  1782. }
  1783.  
  1784.